package com.sky.aspect;

import com.sky.annotation.AutoFillUserId;
import com.sky.constant.JwtClaimsConstant;
import com.sky.enumeration.OperationType;
import com.sky.properties.JwtProperties;
import com.sky.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.Method;

@Aspect
@Slf4j
@Component
public class AutoFillUserIdAspect {
    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private HttpServletRequest request;

    /**
     * 切入点
     * @return
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..))&&@annotation(com.sky.annotation.AutoFillUserId)")
    public void autoFillUserIdPointCut(){}

    /**
     * 前置通知:在通知中进行公共字段UserId赋值
     * @return
     */
    @Around("autoFillUserIdPointCut()")
    public Object autoFillUserId(ProceedingJoinPoint proceedingJoinPoint) {
        log.info("开始进行公共字段userId字段填充");

        //获取方法签名对象
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();

        //获取上面的注解
        AutoFillUserId autoFillUserId = signature.getMethod().getDeclaredAnnotation(AutoFillUserId.class);

        //注解上面的方法
        OperationType value = autoFillUserId.value();

        //获取方法的参数
        Object[] args = proceedingJoinPoint.getArgs();

        //获取当前用户id
        String token = request.getHeader(jwtProperties.getUserTokenName());
        if(token==null){
            try {
               return proceedingJoinPoint.proceed(args);
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
        Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
        Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());

        Object returnVal = null;
        if(value==OperationType.ADDARG){
            args[0]=userId;
            try {
                returnVal = proceedingJoinPoint.proceed(args);

            } catch (Throwable e) {
                e.printStackTrace();
            }
        }else if(value==OperationType.ADDVALUETOOBJECT){
            Object entity=args[0];
            try {
                Method setUserId = entity.getClass().getDeclaredMethod("setUserId", Long.class);
                setUserId.invoke(entity,userId);
                returnVal = proceedingJoinPoint.proceed(args);
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
        return returnVal;
    }



}
